TML-2785: M:N slice 1 — correlated include read through the junction#679
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yml Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
size-limit report 📦
|
@prisma-next/extension-author-tools
@prisma-next/mongo-runtime
@prisma-next/family-mongo
@prisma-next/sql-runtime
@prisma-next/family-sql
@prisma-next/extension-arktype-json
@prisma-next/middleware-cache
@prisma-next/mongo
@prisma-next/extension-paradedb
@prisma-next/extension-pgvector
@prisma-next/extension-postgis
@prisma-next/postgres
@prisma-next/sql-orm-client
@prisma-next/sqlite
@prisma-next/target-mongo
@prisma-next/adapter-mongo
@prisma-next/driver-mongo
@prisma-next/contract
@prisma-next/utils
@prisma-next/config
@prisma-next/errors
@prisma-next/framework-components
@prisma-next/operations
@prisma-next/ts-render
@prisma-next/contract-authoring
@prisma-next/ids
@prisma-next/psl-parser
@prisma-next/psl-printer
@prisma-next/cli
@prisma-next/cli-telemetry
@prisma-next/emitter
@prisma-next/migration-tools
prisma-next
@prisma-next/vite-plugin-contract-emit
@prisma-next/mongo-codec
@prisma-next/mongo-contract
@prisma-next/mongo-value
@prisma-next/mongo-contract-psl
@prisma-next/mongo-contract-ts
@prisma-next/mongo-emitter
@prisma-next/mongo-schema-ir
@prisma-next/mongo-query-ast
@prisma-next/mongo-orm
@prisma-next/mongo-query-builder
@prisma-next/mongo-lowering
@prisma-next/mongo-wire
@prisma-next/sql-contract
@prisma-next/sql-errors
@prisma-next/sql-operations
@prisma-next/sql-schema-ir
@prisma-next/sql-contract-psl
@prisma-next/sql-contract-ts
@prisma-next/sql-contract-emitter
@prisma-next/sql-lane-query-builder
@prisma-next/sql-relational-core
@prisma-next/sql-builder
@prisma-next/target-postgres
@prisma-next/target-sqlite
@prisma-next/adapter-postgres
@prisma-next/adapter-sqlite
@prisma-next/driver-postgres
@prisma-next/driver-sqlite
commit: |
4ee6af6 to
78affcf
Compare
b3bba1c to
e44f8aa
Compare
78affcf to
e4e3004
Compare
e44f8aa to
aaefe75
Compare
9e24a8b to
ed06084
Compare
87de795 to
4763690
Compare
38bcb74 to
c32cd78
Compare
d15ad0b to
5450121
Compare
b7c8ede to
c73f70b
Compare
…ndard (TML-2785) Read slice (correlated include through junction). Bakes the operator integration-test standard (whole-row asserts, explicit select, +implicit nested-M:N case) into the project cross-cutting requirements and slice 1. 3 dispatches: fixture M:N / read code / integration tests. Signed-off-by: Alexey Orlenko's AI Agent <robot@aqrln.net>
Add many-to-many include support via a single correlated subquery that joins the child table to the junction on junction.childColumns = child.targetColumns and correlates to the parent via WHERE junction.parentColumns = parent.parentLocalColumns. Composite keys AND across all column pairs. No LATERAL joins. - IncludeExpr gains `through?: IncludeThroughDescriptor` carrying junction table name, parentColumns, childColumns, targetColumns, and parentLocalColumns. - `resolveIncludeRelation` in collection-contract.ts surfaces `through` from the contract relation when present, resolving field names to column names for the parent local columns. - `Collection.include()` propagates `through` into IncludeExpr via spread. - `buildManyToManyJunctionArtifacts` in query-plan-select.ts builds the JOIN ON expression (BinaryExpr or AndExpr over child column pairs) and the correlated WHERE (BinaryExpr or AndExpr over parent column pairs), producing a non-lateral inner JoinAst to the junction table. - `buildIncludeChildRowsSelect` detects `include.through` and uses the M:N artifacts instead of the FK equality WHERE; `buildDistinctNonLeafChildRowsSelect` receives and applies the same junction joins. - `dispatchWithIncludes` in collection-dispatch.ts forces all `through.parentLocalColumns` (not just `localColumn`) into the parent SELECT augmentation for composite M:N keys. - `buildManyToManyContract` test helper and M:N unit tests covering single-column and composite-key junction shapes, plus a FK path non-regression test. Signed-off-by: Alexey Orlenko's AI Agent <robot@aqrln.net>
…ManyJunctionArtifacts; add M:N+distinct+non-leaf test
F1: the two bare `as AnyExpression` casts in `buildManyToManyJunctionArtifacts` are replaced with
`castAs<AnyExpression>(…!)` — BinaryExpr is a union member of AnyExpression, so the assertion is
type-checked; the non-null assertion is safe because the branch is only taken when `length === 1`.
Adds the `castAs` import from `@prisma-next/utils/casts`. `lint:casts` delta: -1.
F2: new unit test `attaches junction join to baseInner in M:N + distinct + nested non-leaf path`
in the `M:N include correlated subquery` describe block. Constructs a contract with
parents→children (M:N via parent_child junction) + children→grandchildren (FK), sets
`distinct: ['name']` and a nested grandchild include on the M:N IncludeExpr, calls
`compileSelectWithIncludes`, and asserts:
- junction join (`INNER JOIN parent_child`, `lateral: false`) attaches to `baseInner`
(the innermost scalar SELECT inside the ROW_NUMBER wrap), not to the dedup wrapper or
outer distinct SELECT
- correlated WHERE (`parent_child.parent_id = parents.id`) is present at `baseInner`
- no junction join leaks to `innerSelect` or the outer `childRows`
All 493 tests pass; typecheck clean.
Signed-off-by: Alexey Orlenko's AI Agent <robot@aqrln.net>
Adds `mn-include.test.ts` covering the end-to-end M:N include path for
`User.tags` via the `user_tags` junction, using the PGlite harness.
Tests satisfy the operator integration-test standard:
- Whole-row toEqual assertions on every test
- Explicit .select() on 6/7 tests
- One implicit/default-selection test (full User + tags: Tag[] shape)
- Single-execution assertion + no LATERAL in emitted SQL
- Depth-2: M:N tags nested under invitedUsers (1:N self-relation)
- Sibling depth-2: include("tags") alongside include("posts") in one execution
- Edge: user with no tags returns tags: []
- Edge: tag shared by multiple users resolves independently for each
Also extends `setupTestSchema` and adds `seedTags`/`seedUserTags` helpers
to `runtime-helpers.ts` to support the junction table in integration tests.
Signed-off-by: Alexey Orlenko's AI Agent <robot@aqrln.net>
… (TML-2785) Orchestrator artifacts for the read slice (fixture / read-path / integration dispatches; read-path took 3 rounds incl. a truncation recovery). Review log under reviews/ is gitignored. Signed-off-by: Alexey Orlenko's AI Agent <robot@aqrln.net>
…-2605 rebase Carry the resolved junction namespaceId onto IncludeThroughDescriptor and build the correlated include's junction TableSource with it, so the read path emits namespace-qualified SQL for the junction like the rest of the runtime after TML-2605. Signed-off-by: Alexey Orlenko's AI Agent <robot@aqrln.net>
…ough descriptor The contract now carries the junction's namespaceId on through (slice 0); the include descriptor passes it through as a required field instead of re-deriving it from storage. Re-emit the M:N fixture so the User<->Tag through block carries it. Signed-off-by: Alexey Orlenko's AI Agent <robot@aqrln.net>
… M:N contracts (TML-2808 rebase) Main moved namespace tables under entries.table; the hand-built M:N test contracts still used the flat tables record, so table resolution missed them. Signed-off-by: Alexey Orlenko's AI Agent <robot@aqrln.net>
…eated_at) The shared fixture's junction declares a nullable note and a defaulted created_at (exclusion-path coverage for requiredPayloadColumns); create the columns so the schema matches the contract. Signed-off-by: Alexey Orlenko's AI Agent <robot@aqrln.net>
c73f70b to
7e21c60
Compare
Slice 1 of the SQL ORM: Many-to-Many End to End project (Linear project). Reads an M:N relation through its junction.
Overview
db.orm.User.include(tags)now resolves a many-to-many relation to{ …user, tags: Tag[] }in a single correlated subquery that walks parent → junction → target — noLATERAL, no second query. Built on slice 0sResolvedRelation.through.Changes (4 commits)
fcecac5b3— integration fixture gains aUser ↔ TagM:N relation via aUserTagjunction (composite PKuser_id/tag_id);contract.json/.d.tsre-emitted.e587b433c— read path:IncludeExpr.through(surfaced byresolveIncludeRelation), andbuildCorrelatedIncludeProjectiongains an M:N branch —buildManyToManyJunctionArtifactsbuilds a non-LATERAL inner join to the junction (junction.childColumns = target.targetColumns) correlated to the parent (junction.parentColumns = parentanchor), composite-key AND-ed; FK decode path reused. Unit-tested at the AST level.b9c3e9f7b— replace 2 bareascasts withcastAs; add the missing M:N + distinct + non-leaf unit test.d3232cbad— 7 integration tests (PGlite).Integration tests (per the project standard)
Whole-row
toEqual; 6/7 use explicit.select(...)(so adding a model field wont churn assertions); test 5 uses implicit/default selection (fullUser+tags: Tag[]shape); a single-execution / no-LATERALassertion; depth-2 nesting (invitedUsers → tags); edges (user with no tags →tags: []; a tag shared by multiple users).Why
This is the first of the three relation-shaped M:N consumers (read / filter / write) over slice 0s shared
throughprimitive. The correlated-only approach matches the post-TML-2729 read path (no LATERAL to reintroduce).Scope / notes
Read only — filter (TML-2786) and write (TML-2787) are later slices. The fixture is one-directional (
User.tags; reverseTag.usersdeferred — adding it trips a latent create-overload type fragility in unrelated mutation-defaults tests; see the projects unattended-decisions log). Fixture re-emit used atsxbypass because the CLIcontract emitfails on a sandbox config-load env issue — CIfixtures:checkis the real golden-stability gate; please confirm its green (or re-run the canonical emit). Broad integration runs show pre-existing PGlite/WASM JIT flakiness; the M:N tests pass on targeted runs.Refs: TML-2785.